package tom.client.invoice;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import tom.client.DialogExec;
import tom.client.FormLogin;
import tom.client.Library;
import tom.client.LookupInvDlg;
import tom.client.LookupDialog;
import tom.client.OverwriteLevel;
import tom.client.WindMill;
import tom.shared.Customer;
import tom.shared.InvItem;
import tom.shared.Invoice;
import tom.shared.Payment;
import tom.shared.Product;
import tom.shared.Stock;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.datepicker.client.CalendarUtil;
import com.google.gwt.user.datepicker.client.DateBox;
import com.google.gwt.user.datepicker.client.DateBox.DefaultFormat;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.ValueBoxBase.TextAlignment;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.CheckBox;

public class FormInv extends AbsolutePanel implements DialogExec {

	private static final int ITEM_LIMIT = 8;

	protected Integer userLevel;

	protected Library.FormMode mode = Library.FormMode.Clear;

	protected void setMode(Library.FormMode m) {
		mode = Library.checkPermission(m);
		if (mode == Library.FormMode.Clear) {
			btnContact.setEnabled(true);
			btnSearch.setEnabled(true);
			txtContCode.setEnabled(true);
			btnDelItem.setEnabled(false);
			btnPayRemove.setEnabled(false);
			txtSaleDate.setEnabled(false);
			txtShipDate.setEnabled(false);
			txtDueDate.setEnabled(false);
			txtProject.setEnabled(false);
			txtPrjCode.setEnabled(false);
			txtAddr.setEnabled(false);
			txtShipTo.setEnabled(false);
			txtComment.setEnabled(false);
			txtDocRef.setEnabled(false);
			txtCustomer.setEnabled(false);
			txtCode.setEnabled(false);
			txtStatus.setEnabled(false);
			txtBalance.setEnabled(false);
			txtTotalItem.setEnabled(false);
			txtTotalVat.setEnabled(false);
			txtTotalAmt.setEnabled(false);
			txtTotalPaid.setEnabled(false);
			boxSpcDeduct.setEnabled(false);
			boxPayAmt.setEnabled(false);
			txtPayMethod.setEnabled(false);
			txtCheck.setEnabled(false);
			txtPayMeth.setEnabled(false);
			boxCheckDate.setEnabled(false);
			txtProCode.setEnabled(false);
			txtProName.setEnabled(false);
			boxQty.setEnabled(false);
			boxPrice.setEnabled(false);
			boxDiscount.setEnabled(false);
			btnProduct.setEnabled(false);
			btnStock.setEnabled(false);
			btnSave.setEnabled(false);
			btnSave2.setEnabled(false);
			btnSearch.setFocus(true);
			txtPoNr.setEnabled(false);
		} else if (mode == Library.FormMode.Open) {
			btnContact.setEnabled(false);
			btnSearch.setEnabled(true);
			txtContCode.setEnabled(false);
			btnDelItem.setEnabled(false);
			btnPayRemove.setEnabled(false);
			txtSaleDate.setEnabled(false);
			txtShipDate.setEnabled(false);
			txtDueDate.setEnabled(false);
			txtProject.setEnabled(false);
			txtPrjCode.setEnabled(false);
			txtAddr.setEnabled(false);
			txtShipTo.setEnabled(false);
			txtComment.setEnabled(false);
			txtDocRef.setEnabled(false);
			txtCustomer.setEnabled(false);
			txtCode.setEnabled(false);
			txtStatus.setEnabled(false);
			txtBalance.setEnabled(false);
			txtTotalItem.setEnabled(false);
			txtTotalVat.setEnabled(false);
			txtTotalAmt.setEnabled(false);
			txtTotalPaid.setEnabled(false);
			boxSpcDeduct.setEnabled(false);
			boxPayAmt.setEnabled(false);
			txtPayMethod.setEnabled(false);
			txtCheck.setEnabled(false);
			txtPayMeth.setEnabled(false);
			boxCheckDate.setEnabled(false);
			txtProCode.setEnabled(false);
			txtProName.setEnabled(false);
			boxQty.setEnabled(false);
			boxPrice.setEnabled(false);
			boxDiscount.setEnabled(false);
			btnProduct.setEnabled(false);
			btnStock.setEnabled(false);
			btnSave.setEnabled(false);
			btnSave2.setEnabled(false);
			btnSearch.setFocus(true);
			txtPoNr.setEnabled(false);
		} else if (mode == Library.FormMode.Edit
				|| mode == Library.FormMode.Insert) {
			btnContact.setEnabled(true);
			btnSearch.setEnabled(true);
			txtContCode.setEnabled(true);

			btnDelItem.setEnabled(true);
			btnPayRemove.setEnabled(true);
			txtSaleDate.setEnabled(true);
			txtShipDate.setEnabled(true);
			txtDueDate.setEnabled(true);
			txtProject.setEnabled(true);
			txtPrjCode.setEnabled(true);
			txtAddr.setEnabled(true);
			txtShipTo.setEnabled(true);
			txtComment.setEnabled(true);
			txtDocRef.setEnabled(true);
			txtCustomer.setEnabled(true);
			txtCode.setEnabled(true);
			txtStatus.setEnabled(true);
			txtBalance.setEnabled(true);
			txtTotalItem.setEnabled(true);
			txtTotalVat.setEnabled(true);
			txtTotalAmt.setEnabled(true);
			txtTotalPaid.setEnabled(true);
			boxSpcDeduct.setEnabled(true);
			boxPayAmt.setEnabled(true);
			txtPayMethod.setEnabled(true);
			txtCheck.setEnabled(true);
			txtPayMeth.setEnabled(true);
			boxCheckDate.setEnabled(true);
			txtProCode.setEnabled(true);
			txtProName.setEnabled(true);
			boxQty.setEnabled(true);
			boxPrice.setEnabled(true);
			boxDiscount.setEnabled(true);
			btnProduct.setEnabled(true);
			btnStock.setEnabled(true);
			btnSave.setEnabled(true);
			btnSave2.setEnabled(true);
			txtPoNr.setEnabled(true);

		}

	}

	AsyncCallback<Boolean> rollbackCallback = new AsyncCallback<Boolean>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(Boolean result) {
			if (result) {
				int invNo = Integer.valueOf(txtCode.getText());
				clearScreen();
				Library.getSaleService().selectInvoice(invNo, invCallback);
			} else
				Window.alert("การถอยสถานะทำไม่สำเร็จ!");
		}
	};

	protected Customer customer;

	AsyncCallback<Customer> custCallback = new AsyncCallback<Customer>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(Customer result) {
			customer = result;
			if (mode == Library.FormMode.Insert
					|| mode == Library.FormMode.Edit) {
				boolean valid = true;
				if (customer.custStatus.compareTo("2") > 0) {
					Window.alert("สถานะแก้ไขไม่ได้");
					// clearScreen();
					valid = false;
				} else if (customer.custLimit > 1
						&& customer.custBalance > customer.custLimit) {
					Window.alert("มียอดค้างชำระเกินวงเงิน");
					// clearScreen();
					valid = false;
				}
				if (valid) {
					Date today = new Date();
					invoice.contCode = result.contCode;
					invoice.contactAddr = result.contact.label;
					CalendarUtil.addDaysToDate(today, result.custDueDay);
					invoice.dueDate = today;

					// if (txtContCode.getValue().equals("999999")) {
					// txtPayMeth.setValue("1");
					// txtPayMethod.setValue("เงินสด");
					// } else {
					// txtPayMeth.setValue("0");
					// txtPayMethod.setValue("ค้างชำระ");
					// }
					refreshInvoice();
					tabPanel.selectTab(1);
					txtProCode.setFocus(true);
					txtProCode.selectAll();
				} else {
					clearScreen();
				}
			} else {
				refreshInvoice(); // กรณีเปิดดูอย่างเดียว
			}
		}
	};

	Invoice invoice;

	AsyncCallback<String> insInvCallback = new AsyncCallback<String>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(String result) {
			// Window.alert("บันทึก " + result);
			btnSave.setEnabled(true);
			btnSave2.setEnabled(true);
			Library.getSaleService().selectInvoice(Integer.valueOf(result),
					invCallback);
		}
	};

	AsyncCallback<Invoice> invCallback = new AsyncCallback<Invoice>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(Invoice result) {
			if (result != null) {
				if (result.status.compareTo("0") > 0)
					setMode(Library.FormMode.Open);
				else
					setMode(Library.FormMode.Edit);
				invoice = result;
				if (invoice.contCode != null)
					Library.getSaleService().selectCustomer(invoice.contCode,
							custCallback);
				refreshPayments();
				refreshItem();
				refreshInvoice();
			} else {
				clearScreen();
			}
		}
	};

	protected InvItem curItem;
	AsyncCallback<Product> proCallback = new AsyncCallback<Product>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(Product result) {
			if (result != null) {
				if (result.stocks.size() > 0) {
					// txtProName.setText(result.name);
					// boxQty.setValue(1.0);
					// boxPrice.setValue(result.sellPrice);
					// boxDiscount.setValue(result.discount);

					if (mode == Library.FormMode.Insert
							|| mode == Library.FormMode.Edit) {
						if (curItem == null) {
							curItem = new InvItem();
							invoice.items.add(curItem);

						}
						curItem.invNo = invoice.invNo;
						curItem.proCode = result.proCode;
						curItem.qty = 1.0;
						curItem.unitPrice = result.sellPrice;
						curItem.proName = result.name;
						curItem.discount = result.discount;
						curItem.stkCode = result.stkCode;
						curItem.vat = vat.get(Integer.parseInt(result.sellVAT));
						curItem.unit = result.unit;
						curItem.product = result;
						curItem.stocks = result.stocks;
						refreshItem();
						refreshInvoice();
						boxQty.setFocus(true);
						boxQty.selectAll();
					}
				} else {
					Window.alert("ไม่มีข้อมูลสต็อค");
				}
			} else {
				Window.alert("ไม่มีข้อมูลสินค้า");
			}
		}
	};

	protected Payment curPay;

	public void clearScreen() {
		// Library.getService().verify(FormLogin.frmLogin.getUser(),
		// FormLogin.frmLogin.getPassword(), levelCallback);
		userLevel = FormLogin.currUser.getLevel();
		invoice = new Invoice();
		invoice.systemKind = "D";
		invoice.docuKind = "I";
		customer = new Customer();
		curItem = null;
		curPay = new Payment();
		curPay.payMethod = 0;
		curPay.payMethodName = "ค้างชำระ";
		txtCheck.setVisible(false);
		boxCheckDate.setVisible(false);
		label_2.setVisible(false);
		label_3.setVisible(false);
		setMode(Library.FormMode.Clear);
		btnManager.setVisible(false);
		btnRePrint.setVisible(false);
		refreshPayments();
		refreshItem();
		refreshInvoice();
		txtContCode.setFocus(true);
		txtContCode.selectAll();
	}

	protected void refreshInvoice() {
		lbDocuKind.setText(invoice.docuKindName);
		txtDocRef.setText(invoice.docRef);
		txtCustomer.setText(customer.contact.name);
		txtContCode.setText(invoice.contCode);
		txtSaleDate.setValue(invoice.invDate);
		txtShipDate.setValue(invoice.shipDate);
		txtDueDate.setValue(invoice.dueDate);
		txtPoNr.setText(invoice.poNr);
		txtPrjCode.setText(invoice.projCode);
		txtAddr.setText(invoice.contactAddr);
		txtShipTo.setText(invoice.shipTo);
		txtComment.setText(invoice.note);
		lbTextTotal.setText(invoice.totalAmtText);
		String x = Library.moneyFormat(customer.custLimit
				- customer.custBalance);
		txtBalance.setValue(x);
		txtTotalItem.setValue(Library.moneyFormat(invoice.totalItem));
		txtTotalAmt.setValue(Library.moneyFormat(invoice.totalAmt));
		txtTotalPaid.setValue(Library.moneyFormat(invoice.totalPaid));
		double bal = invoice.totalAmt - invoice.totalPaid;
		txtBal.setValue(Library.moneyFormat(bal));
		boxPayAmt.setValue(bal);
		// Window.alert(invoice.totalAmtText + " - " + invoice.totalPaid);
		txtTotalVat.setValue(Library.moneyFormat(invoice.totalVat));
		boxSpcDeduct.setValue(Library.moneyFormat(invoice.spcDeduct));
		// if (invoice.totalPaid == 0) {
		// btnSave.setText("อัพโหลด");
		// } else {
		// btnSave.setText("บันทึก");
		// }
	}

	protected void refreshPayments() {
		if (mode == Library.FormMode.Insert || mode == Library.FormMode.Edit)
			calcPay();
		if (curPay == null) {
			curPay = new Payment();
			curPay.payMethod = 0;
			curPay.payMethodName = "ค้างชำระ";
			double paid = 0;
			for (Payment p : invoice.payments) {
				paid += p.amt;
			}
			curPay.amt = invoice.totalAmt - paid;
		}
		boxPayAmt.setValue(curPay.amt);
		// txtPayMeth.setText(curPay.payMethod.toString());
		txtPayMethod.setText(curPay.payMethodName);
		txtCheck.setValue(curPay.chkCardNo);
		txtPayMeth.setValue(curPay.payMethod.toString());
		boxCheckDate.setValue(curPay.checkDate);

		txtTotalItem.setText(Library.moneyFormat(invoice.totalItem));
		payData.setList(invoice.payments);
		payData.refresh();
	}

	protected void calcPay() {

	}

	protected void refreshItem() {
		if (mode == Library.FormMode.Insert || mode == Library.FormMode.Edit)
			calcItem();
		if (curItem == null) {
			txtProCode.setText(null);
			txtProName.setText(null);
			boxQty.setValue(null);
			boxPrice.setValue(null);
			boxDiscount.setValue(null);
			lbOrder.setText(null);
			stkCombo.clear();
		} else {
			lbOrder.setText(findOrder(curItem) + " / " + invoice.items.size());
			WindMill.setStatus(this.getTitle() + " รายการที่ "
					+ lbOrder.getText());
			txtProCode.setText(curItem.proCode);
			txtProName.setText(curItem.proName);
			boxQty.setValue(curItem.qty);
			boxPrice.setValue(curItem.unitPrice);
			boxDiscount.setValue(curItem.discount);
			stkCombo.clear();
			for (int row = 0; row < curItem.stocks.size(); row++) {
				Stock stk = curItem.stocks.get(row);
				stkCombo.addItem(stk.stkCode + " balance : " + stk.balance,
						stk.stkCode);
				if (stk.stkCode.equals(curItem.stkCode)) {
					stkCombo.setSelectedIndex(row);
				}
			}
		}
		// txtTotal.setText(Library.moneyFormat(invoice.totalItem));
		// txtTotalVat.setText(Library.moneyFormat(invoice.totalVat));
		// txtTotalAmt.setText(Library.moneyFormat(invoice.totalAmt));
		// lbTextTotal.setText(Library.moneyText(invoice.totalAmt));
		itemData.setList(invoice.items);
		itemData.refresh();
	}

	protected static FormInv panel;

	public static FormInv getPanel() {
		if (panel == null)
			panel = GWT.create(FormInv.class);
		return panel;
	}

	protected static final String pWidth = "900px";

	protected static final String pHeight = "500px";

	protected final ListDataProvider<InvItem> itemData = new ListDataProvider<InvItem>();
	protected final CellTable<InvItem> itemTable = new CellTable<InvItem>();
	protected final SingleSelectionModel<InvItem> itemSelection = new SingleSelectionModel<InvItem>();

	protected final ListDataProvider<Payment> payData = new ListDataProvider<Payment>();
	protected final CellTable<Payment> payTable = new CellTable<Payment>();
	protected final SingleSelectionModel<Payment> paySelection = new SingleSelectionModel<Payment>();

	protected List<Double> vat;

	protected final DateBox txtSaleDate;

	protected final DateBox txtShipDate;

	protected final DateBox txtDueDate;

	protected final TextBox txtProject;

	protected final TextBox txtPrjCode;

	protected final TextArea txtAddr;

	protected final TextArea txtShipTo;

	protected final TextArea txtComment;

	protected final TextBox txtDocRef;

	protected final TextBox txtCustomer;

	protected final TextBox txtCode;

	protected final TextBox txtContCode;

	protected final TextBox txtStatus;

	protected final TextBox txtBalance;

	protected final TextBox txtTotalItem;

	protected final TextBox txtTotalVat;

	protected final TextBox txtTotalAmt;

	protected final TextBox txtTotalPaid;

	protected final TextBox boxSpcDeduct;

	protected final TextBox txtBal;

	protected DoubleBox boxPayAmt = new DoubleBox();

	protected TextBox txtPayMethod = new TextBox();

	protected final TextBox txtCheck = new TextBox();

	protected final TextBox txtPayMeth = new TextBox();

	protected final DateBox boxCheckDate = new DateBox();

	protected final Button btnContact;

	protected final TextBox txtProCode = new TextBox();

	protected final TextBox txtProName = new TextBox();

	protected final DoubleBox boxQty = new DoubleBox();

	protected final DoubleBox boxPrice = new DoubleBox();

	protected final DoubleBox boxDiscount = new DoubleBox();

	protected final Button btnProduct = new Button("?");

	protected Label lbTextTotal = new Label();

	protected final Label lblDueDate;

	protected final Button btnStock = new Button("เลือกคลัง");

	protected final Button btnSave = new Button("อัพโหลด");

	protected final Button btnSave2 = new Button("บันทึก");

	protected final Button btnSearch = new Button("ค้นหา");

	protected final Button btnDelItem = new Button("ลบรายการ");

	protected final Button btnPayRemove = new Button("ลบ");

	protected final TabPanel tabPanel;

	protected final Button btnPrint;

	protected final Label label_2 = new Label("เลขที่เช็ค");

	protected final Label label_3 = new Label("วันที่บัตร");

	protected final ListBox stkCombo = new ListBox();

	protected final Label lbOrder = new Label("");

	protected final Button btnManager = new Button("ถอยสเตตัส");

	protected final Button btnRePrint = new Button("พิมพ์บิลซ้ำ");

	protected final CheckBox chkBoxService = new CheckBox("บิลบริการ");

	protected final Label lbDocuKind = new Label("");

	protected final TextBox txtPoNr;

	public FormInv() {
		setSize(pWidth, pHeight);

		tabPanel = new TabPanel();
		add(tabPanel, 0, 100);
		tabPanel.setSize(pWidth, "380px");

		AbsolutePanel invPanel = new AbsolutePanel();
		invPanel.setSize(pWidth, "360px");

		tabPanel.add(invPanel, "รายละเอียดบิล");
		tabPanel.add(createItemPanel(), "สินค้า");
		tabPanel.add(createPaymentPanel(), "ชำระเงิน");

		Label label_1 = new Label("วันที่บิล");
		invPanel.add(label_1, 10, 10);

		Label label_2 = new Label("วันที่ส่งของ");
		invPanel.add(label_2, 10, 41);

		Label label_3 = new Label("วันครบกำหนด");
		invPanel.add(label_3, 10, 71);

		Label label_4 = new Label("โครงการ");
		invPanel.add(label_4, 10, 103);

		Label label_5 = new Label("ที่อยู่จัดส่ง");
		invPanel.add(label_5, 383, 103);

		Label label_6 = new Label("หมายเหตุ");
		invPanel.add(label_6, 383, 200);

		Label lblNewLabel = new Label("ที่อยู่ใบกำกับภาษี");
		invPanel.add(lblNewLabel, 383, 10);

		invPanel.add(lbTextTotal, 348, 320);
		// add(lbTextTotal, 625, 15);

		txtSaleDate = new DateBox();
		txtSaleDate.setValue(new Date());
		txtSaleDate.setFormat(new DefaultFormat(Library.DATE_FORMAT));
		invPanel.add(txtSaleDate, 89, 7);
		txtSaleDate.setSize("80px", "18px");

		txtShipDate = new DateBox();
		txtShipDate.setValue(new Date());
		txtShipDate.setFormat(new DefaultFormat(Library.DATE_FORMAT));
		invPanel.add(txtShipDate, 89, 38);
		txtShipDate.setSize("80px", "18px");

		txtDueDate = new DateBox();
		txtDueDate.setValue(new Date());
		txtDueDate.setFormat(new DefaultFormat(Library.DATE_FORMAT));
		invPanel.add(txtDueDate, 89, 68);
		txtDueDate.setSize("80px", "18px");

		lblDueDate = new Label("");
		invPanel.add(lblDueDate, 205, 70);

		txtProject = new TextBox();
		invPanel.add(txtProject, 143, 100);
		txtProject.setSize("150px", "16px");

		txtPrjCode = new TextBox();
		invPanel.add(txtPrjCode, 89, 100);
		txtPrjCode.setSize("38px", "16px");
		// txtPrjCode.setVisible(false);

		Button btnProject = new Button("?");
		invPanel.add(btnProject, 309, 100);
		btnProject.setSize("30px", "28px");
		btnProject.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				LookupDialog.show("เลือก Project", "prjCode", txtPrjCode);
			}
		});

		Label lbPoNr = new Label("PO#");
		invPanel.add(lbPoNr, 10, 135);

		txtPoNr = new TextBox();
		invPanel.add(txtPoNr, 89, 130);
		txtPoNr.setSize("80px", "16px");

		txtAddr = new TextArea();
		invPanel.add(txtAddr, 480, 10);
		txtAddr.setSize("350px", "85px");

		txtShipTo = new TextArea();
		invPanel.add(txtShipTo, 480, 103);
		txtShipTo.setSize("350px", "85px");

		txtComment = new TextArea();
		invPanel.add(txtComment, 480, 200);
		txtComment.setSize("350px", "85px");

		// Button btnCustomer = new Button("?");
		// invPanel.add(btnCustomer, 235, 98);
		// btnCustomer.setSize("30px", "24px");
		// btnCustomer.addClickHandler(new ClickHandler() {
		// public void onClick(ClickEvent event) {
		// LookupDialog.show("เลือกลูกค้า", "contCode", txtContCode);
		// }
		// });

		btnSave.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				setFields();
				if (invoice.payments.size() != 0)
					invoice.upload = 1;
				btnSave.setEnabled(false);
				if (mode == Library.FormMode.Insert) {
					if (chkBoxService.getValue())
						invoice.docuKind = "S";
					Library.getSaleService().insertInvoice(invoice,
							insInvCallback);
				} else
					Library.getSaleService().updateInvoice(invoice,
							insInvCallback);

			}

		});
		add(btnSave, 806, 35);
		btnSave.setSize("88px", "30px");
		btnSave.setText("อัพโหลด");
		btnSearch.addKeyPressHandler(new KeyPressHandler() {

			@Override
			public void onKeyPress(KeyPressEvent event) {
				// if (event.getCharCode() )
			}
		});

		btnSearch.addKeyDownHandler(new KeyDownHandler() {
			@Override
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_PAGEUP) {
					OverwriteLevel.show(FormInv.this, "022saleinvoice");
				}
				if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
					clearScreen();
				}
			}
		});
		btnSearch.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				LookupInvDlg.show("เลือกบิล", txtCode);
			}
		});

		btnSearch.setText("ค้นหา");
		add(btnSearch, 192, 5);
		btnSearch.setSize("88px", "26px");

		Label label = new Label("เลขที่บิล");
		add(label, 0, 2);
		txtDocRef = new TextBox();
		add(txtDocRef, 76, 2);
		txtDocRef.setSize("100px", "16px");

		Label label1 = new Label("รหัสลูกค้า");
		add(label1, 0, 40);
		txtCustomer = new TextBox();
		txtCustomer.setStyleName("gwt-TextBoxR");
		txtCustomer.setReadOnly(true);
		add(txtCustomer, 176, 37);
		txtCustomer.setSize("180px", "18px");

		Label label2 = new Label("วงเงินคงเหลือ");
		add(label2, 0, 72);

		Label label4 = new Label("รวมเงิน");
		add(label4, 440, 72);

		Label label3 = new Label("ชำระแล้ว");
		add(label3, 634, 1);

		Label lblNewLabel_1 = new Label("ค่าสินค้า");
		add(lblNewLabel_1, 440, 2);

		Label lblNewLabel_6 = new Label("ลดพิเศษ");
		add(lblNewLabel_6, 440, 47);

		Label label_7 = new Label("ภาษี");
		add(label_7, 440, 25);

		txtCode = new TextBox();
		txtCode.setReadOnly(true);
		add(txtCode, 130, -15);
		txtCode.setSize("30px", "18px");
		txtCode.setVisible(false);
		txtCode.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					Library.getSaleService().selectInvoice(
							Integer.valueOf(txtCode.getText()), invCallback);
				} else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
					clearScreen();
				} else if (event.isControlKeyDown()
						&& event.getNativeKeyCode() == ' ') {
					// btnSearchContact.click();
				}
			}
		});

		txtContCode = new TextBox();
		// txtContCode.addValueChangeHandler(new ValueChangeHandler<String>() {
		// public void onValueChange(ValueChangeEvent<String> event) {
		// Library.getSaleService().selectCustomer(txtContCode.getText(),
		// custCallback);
		// }
		// });
		txtContCode.setText("999999");
		add(txtContCode, 76, 35);
		txtContCode.setSize("50px", "16px");
		txtContCode.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					if (mode != Library.FormMode.Edit)
						setMode(Library.FormMode.Insert);
					Library.getSaleService().selectCustomer(
							txtContCode.getText(), custCallback);
					// selectContactDebter();
				} else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
					clearScreen();
				} else if (event.isControlKeyDown()
						&& event.getNativeKeyCode() == ' ') {
					btnContact.click();
				}
			}
		});

		btnContact = new Button("?");
		add(btnContact, 140, 35);
		btnContact.setSize("30px", "28px");
		btnContact.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				LookupDialog.show("เลือกลูกค้า", "contCode", txtContCode);
			}
		});

		txtStatus = new TextBox();
		txtStatus.setStyleName("gwt-TextBoxR");
		txtStatus.setReadOnly(true);
		add(txtStatus, 20, -15);
		txtStatus.setSize("100px", "18px");
		txtStatus.setVisible(false);

		txtBalance = new TextBox();
		txtBalance.setStyleName("gwt-TextBoxR");
		txtBalance.setText("0.0");
		txtBalance.setReadOnly(true);
		txtBalance.setMaxLength(10);
		txtBalance.setAlignment(TextAlignment.RIGHT);
		add(txtBalance, 76, 70);
		txtBalance.setSize("100px", "18px");

		txtTotalItem = new TextBox();
		txtTotalItem.setStyleName("gwt-TextBoxR");
		txtTotalItem.setText("0.0");
		txtTotalItem.setReadOnly(true);
		txtTotalItem.setMaxLength(10);
		txtTotalItem.setAlignment(TextAlignment.RIGHT);
		add(txtTotalItem, 505, 0);
		txtTotalItem.setSize("104px", "18px");

		txtTotalVat = new TextBox();
		txtTotalVat.setStyleName("gwt-TextBoxR");
		txtTotalVat.setText("0.0");
		txtTotalVat.setReadOnly(true);
		txtTotalVat.setMaxLength(10);
		txtTotalVat.setAlignment(TextAlignment.RIGHT);
		add(txtTotalVat, 505, 24);
		txtTotalVat.setSize("105px", "18px");

		txtTotalAmt = new TextBox();
		txtTotalAmt.setStyleName("gwt-TextBoxR");
		txtTotalAmt.setText("0.0");
		txtTotalAmt.setReadOnly(true);
		txtTotalAmt.setMaxLength(10);
		txtTotalAmt.setAlignment(TextAlignment.RIGHT);
		add(txtTotalAmt, 505, 77);
		txtTotalAmt.setSize("105px", "18px");

		txtTotalPaid = new TextBox();
		txtTotalPaid.setStyleName("gwt-TextBoxYellow");
		txtTotalPaid.setText("0.0");
		txtTotalPaid.setReadOnly(true);
		txtTotalPaid.setMaxLength(10);
		txtTotalPaid.setAlignment(TextAlignment.RIGHT);
		add(txtTotalPaid, 691, 0);
		txtTotalPaid.setSize("105px", "18px");

		boxSpcDeduct = new TextBox();
		boxSpcDeduct.addFocusHandler(new FocusHandler() {
			public void onFocus(FocusEvent event) {
				boxSpcDeduct.selectAll();
			}
		});
		boxSpcDeduct.setText("0.0");
		boxSpcDeduct.setMaxLength(10);
		boxSpcDeduct.setAlignment(TextAlignment.RIGHT);
		add(boxSpcDeduct, 505, 48);
		boxSpcDeduct.setSize("98px", "16px");

		Button btnClear = new Button("เคลียร์");
		btnClear.setVisible(false);
		btnClear.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				clearScreen();
			}
		});
		add(btnClear, 177, -15);
		btnClear.setSize("88px", "26px");

		txtBal = new TextBox();
		txtBal.setText("0.0");
		txtBal.setStyleName("gwt-TextBoxYellow");
		txtBal.setReadOnly(true);
		txtBal.setMaxLength(10);
		txtBal.setAlignment(TextAlignment.RIGHT);
		add(txtBal, 691, 24);
		txtBal.setSize("105px", "18px");

		Label label_8 = new Label("คงค้าง");
		add(label_8, 634, 25);
		label_8.setSize("51px", "18px");

		btnSave2.setText("บันทึก");
		add(btnSave2, 806, 2);
		btnSave2.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (invoice.contCode.equals("999999")
						&& !(invoice.totalPaid.toString()
								.equals(invoice.totalAmt.toString()))) {
					Window.alert("ชำระเงินสดเต็มจำนวน " + invoice.totalPaid
							+ " : " + invoice.totalAmt);
				} else {
					if (boxPayAmt.getValue() > 0) {
						insertPayment();
					}
					if (invoice.payments.size() > 0) {
						invoice.upload = 1;
						setFields();
						btnSave2.setEnabled(false);
						if (mode == Library.FormMode.Insert)
							Library.getSaleService().insertInvoice(invoice,
									insInvCallback);
						else
							Library.getSaleService().updateInvoice(invoice,
									insInvCallback);
					}
				}
			}
		});
		btnSave2.setSize("88px", "30px");

		btnPrint = new Button("พิมพ์");
		btnPrint.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (mode == Library.FormMode.Open) {
					if (invoice.status.compareTo("1") >= 0) {
						final Map<String, Object> params = new HashMap<String, Object>();
						params.put("invNo", invoice.invNo.toString());
						params.put("comCode", "sn");
						// Window.alert("print report");
						printReport(params);
					}
				} else {
					Window.alert("กรุณาบันทึกก่อนพิมพ์");
				}
			}
		});
		btnPrint.setText("พิมพ์");
		add(btnPrint, 806, 69);
		btnPrint.setSize("88px", "30px");

		btnManager.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				if (Window.confirm("ยกเลิกการตัดสต็อคและชำระเงิน ?"))
					Library.getSaleService().rollbackInvoice(
							FormInv.this.invoice.invNo, rollbackCallback);
			}
		});
		add(btnManager, 630, 69);
		btnManager.setSize("82px", "30px");

		btnRePrint.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				if (Window.confirm("พิมพ์บิลนี้ซ้ำหรือไม่ ?")) {
					final Map<String, Object> params = new HashMap<String, Object>();
					params.put("invNo", invoice.invNo.toString());
					params.put("comCode", "sn");
					params.put("reprint", "yes");
					printReport(params);
				}
			}
		});
		add(btnRePrint, 718, 69);
		btnRePrint.setSize("82px", "30px");

		add(chkBoxService, 205, 72);

		add(lbDocuKind, 284, 9);
		lbDocuKind.setSize("119px", "18px");

		boxSpcDeduct.addValueChangeHandler(new ValueChangeHandler<String>() {
			public void onValueChange(ValueChangeEvent<String> event) {
				invoice.spcDeduct = Double.valueOf(boxSpcDeduct.getValue());
				// invoice.totalAmt = invoice.totalItem + invoice.totalVat
				// - invoice.spcDeduct;
				// txtTotalAmt.setText(Library.moneyFormat(invoice.totalAmt));
				// lbTextTotal.setText(Library.moneyText(invoice.totalAmt));
				refreshItem();
				refreshInvoice();
				boxSpcDeduct.selectAll();
			}
		});
		//addShortCut();
		tabPanel.selectTab(1);
		Library.getStkService().selectVAT(vatCallback);
		clearScreen();
	}

	protected Panel createPaymentPanel() {
		VerticalPanel vPanel1 = new VerticalPanel();

		paySelection
				.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
					@Override
					public void onSelectionChange(SelectionChangeEvent event) {
						curPay = paySelection.getSelectedObject();
						refreshPayments();
					}
				});

		vPanel1.setSize("100%", "100%");
		AbsolutePanel editPanel = new AbsolutePanel();
		editPanel.setSize("880px", "80px");
		vPanel1.add(editPanel);

		Label label = new Label("ชำระ");
		editPanel.add(label, 10, 10);

		boxPayAmt.setAlignment(TextAlignment.RIGHT);
		editPanel.add(boxPayAmt, 91, 7);
		boxPayAmt.setSize("100px", "18px");
		boxPayAmt.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					insertPayment();
				} else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
				} else if (event.isControlKeyDown()
						&& event.getNativeKeyCode() == ' ') {
				}
			}
		});

		Label label_1 = new Label("วิธีชำระ");
		editPanel.add(label_1, 10, 37);

		txtPayMethod.setStyleName("gwt-TextBoxR");
		txtPayMethod.setReadOnly(true);
		txtPayMethod.setText("เงินสดขาย");
		editPanel.add(txtPayMethod, 90, 34);
		txtPayMethod.setSize("180px", "18px");

		Button btnPayMeth = new Button("?");
		editPanel.add(btnPayMeth, 275, 33);
		btnPayMeth.setSize("24px", "24px");
		btnPayMeth.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				LookupDialog.show("เลือกประเภทการชำระ", "payMeth", txtPayMeth,
						txtPayMethod);
			}
		});

		ScrollPanel paymentPanel = new ScrollPanel();
		paymentPanel.setSize("895px", "280px");
		vPanel1.add(paymentPanel);

		payTable.setStyleName("table");
		paymentPanel.setWidget(payTable);

		payData.addDataDisplay(payTable);
		payTable.setPageSize(10);
		payTable.setTableLayoutFixed(true);
		payTable.setAccessKey('x');
		// itemTable.setSize("100%", "100%");
		payTable.setHeight("100%");
		// payTable.setWidth("100%", true);
		payTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);

		TextColumn<Payment> colPayDate = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				if (object.payDate == null)
					return null;
				else
					return Library.DATE_FORMAT.format(object.payDate);
			}
		};
		payTable.addColumn(colPayDate, "วันที่ชำระเงิน");
		payTable.setColumnWidth(colPayDate, "100px");

		TextColumn<Payment> colPayMeth = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				return object.payMethodName;
			}
		};
		payTable.addColumn(colPayMeth, "วิธีชำระ");
		payTable.setColumnWidth(colPayMeth, "150px");

		TextColumn<Payment> colPayAmt = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				return Library.moneyFormat(object.amt);
			}
		};
		colPayAmt.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		payTable.addColumn(colPayAmt, "Amount");
		payTable.setColumnWidth(colPayAmt, "50px");

		TextColumn<Payment> colCard = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				return object.chkCardNo;
			}
		};
		payTable.addColumn(colCard, "เลขที่เช็ค/บัตร");
		payTable.setColumnWidth(colCard, "100px");

		TextColumn<Payment> colExpDate = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				if (object.checkDate == null)
					return null;
				else
					return Library.DATE_FORMAT.format(object.checkDate);
			}
		};
		payTable.addColumn(colExpDate, "วันที่เช็ค");
		payTable.setColumnWidth(colExpDate, "100px");

		editPanel.add(txtCheck, 473, 6);
		txtCheck.setSize("100px", "18px");
		txtCheck.setVisible(false);

		label_2.setVisible(false);

		editPanel.add(label_2, 392, 10);

		txtPayMeth.setReadOnly(true);
		txtPayMeth.setVisible(false);
		editPanel.add(txtPayMeth, 252, 33);
		txtPayMeth.setSize("20px", "18px");
		txtPayMeth.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				txtCheck.setVisible(txtPayMeth.getText().equals("2"));
				label_2.setVisible(txtCheck.isVisible());
				boxCheckDate.setVisible(txtPayMeth.getText().equals("2")
						|| txtPayMeth.getText().equals("3")
						|| txtPayMeth.getText().equals("4")
						|| txtPayMeth.getText().equals("5")
						|| txtPayMeth.getText().equals("6")
						|| txtPayMeth.getText().equals("7")
						|| txtPayMeth.getText().compareTo("22") >= 0);
				label_3.setVisible(boxCheckDate.isVisible());
				if (txtPayMeth.getText().equals("2")) {
					label_3.setText("วันที่เช็ค");
				}
				if (txtPayMeth.getText().equals("3")
						|| txtPayMeth.getText().equals("4")
						|| txtPayMeth.getText().equals("5")
						|| txtPayMeth.getText().equals("6")) {
					label_3.setText("วันที่บัตรเครดิต");
				}
				if (txtPayMeth.getText().equals("7")
						|| txtPayMeth.getText().compareTo("22") >= 0) {
					label_3.setText("วันที่โอน");
				}
			}
		});

		editPanel.add(label_3, 392, 37);
		label_3.setSize("120px", "18px");
		label_3.setVisible(false);

		boxCheckDate.setFormat(new DefaultFormat(Library.DATE_FORMAT));
		editPanel.add(boxCheckDate, 473, 34);
		boxCheckDate.setSize("105px", "18px");
		boxCheckDate.setVisible(false);

		Button btnPay = new Button("ยืนยันชำระ");
		btnPay.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				insertPayment();
			}
		});

		editPanel.add(btnPay, 720, 7);
		btnPay.setSize("90px", "30px");

		btnPayRemove.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				deletePayment();
			}

		});
		btnPayRemove.setTabIndex(-1);

		editPanel.add(btnPayRemove, 720, 40);
		btnPayRemove.setSize("90px", "30px");

		payTable.setSelectionModel(paySelection);

		// paySelection
		// .addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
		// @Override
		// public void onSelectionChange(SelectionChangeEvent event) {
		// curPay = paySelection.getSelectedObject();
		// refreshPayments();
		// }
		// });

		// DoubleBox doubleBox = new DoubleBox();
		// editPanel.add(doubleBox, 95, 10);
		//
		// TextBox textBox = new TextBox();
		// editPanel.add(textBox, 91, 42);
		//
		// Label lblNewLabel_5 = new Label("ส่วนลดพิเศษ");
		// editPanel.add(lblNewLabel_5, 10, 10);
		return vPanel1;
	}

	protected Panel createItemPanel() {
		VerticalPanel vPanel = new VerticalPanel();
		vPanel.setSize("100%", "100%");
		AbsolutePanel editPanel = new AbsolutePanel();
		editPanel.setSize("895px", "80px");
		vPanel.add(editPanel);
		ScrollPanel listPanel = new ScrollPanel();
		listPanel.setSize("895px", "280px");
		vPanel.add(listPanel);

		itemTable.setStyleName("table");
		listPanel.setWidget(itemTable);
		itemTable.setSelectionModel(itemSelection);

		itemSelection
				.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
					@Override
					public void onSelectionChange(SelectionChangeEvent event) {
						curItem = itemSelection.getSelectedObject();
						refreshItem();
					}
				});

		TextColumn<InvItem> colProCode = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return object.proCode;
			}
		};
		colProCode.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
		// colProCode.setCellStyleNames("table");
		itemTable.addColumn(colProCode, "รหัสสินค้า");
		itemTable.setColumnWidth(colProCode, "95px");

		TextColumn<InvItem> colStkLoc = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return object.stkCode;
			}
		};
		colStkLoc.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
		// colProCode.setCellStyleNames("table");
		itemTable.addColumn(colStkLoc, "คลัง");
		itemTable.setColumnWidth(colStkLoc, "30px");

		TextColumn<InvItem> colProName = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return object.proName;
			}
		};
		colProName.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
		itemTable.addColumn(colProName, "ชื่อสินค้า");
		itemTable.setColumnWidth(colProName, "250px");

		TextColumn<InvItem> colQty = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				if (object.qty == null)
					object.qty = 0.0;
				return String.valueOf(object.qty);
			}
		};
		colQty.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
		colQty.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		itemTable.addColumn(colQty, "จำนวน");
		itemTable.setColumnWidth(colQty, "35px");

		TextColumn<InvItem> colUnitPrice = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return Library.moneyFormat(object.unitPrice);
			}
		};
		colUnitPrice.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
		colUnitPrice.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		itemTable.addColumn(colUnitPrice, "ราคา");
		itemTable.setColumnWidth(colUnitPrice, "65px");

		TextColumn<InvItem> colUnit = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return object.unit;
			}
		};
		colUnit.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
		itemTable.addColumn(colUnit, "หน่วย");
		itemTable.setColumnWidth(colUnit, "40px");

		TextColumn<InvItem> colDisc = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return String.valueOf(object.discount);
			}
		};
		colDisc.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
		colDisc.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		itemTable.addColumn(colDisc, "ลด %");
		itemTable.setColumnWidth(colDisc, "40px");

		TextColumn<InvItem> colTotalItem = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return Library.moneyFormat(object.total);
			}
		};
		colTotalItem.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
		colTotalItem.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		itemTable.addColumn(colTotalItem, "รวม");
		itemTable.setColumnWidth(colTotalItem, "75px");

		// itemData.setList(itemList);
		itemData.addDataDisplay(itemTable);
		itemTable.setPageSize(40);
		itemTable.setTableLayoutFixed(true);
		itemTable.setAccessKey('x');
		itemTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
		itemTable.setHeight("100%");
		itemTable.setWidth("100%", true);

		btnProduct.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				LookupDialog.show("เลือกสินค้า", "proCode", txtProCode);
			}
		});
		editPanel.add(btnProduct, 204, 4);
		btnProduct.setSize("30px", "30px");

		editPanel.add(txtProCode, 70, 4);
		txtProCode.setSize("120px", "18px");
		txtProCode.addValueChangeHandler(new ValueChangeHandler<String>() {
			public void onValueChange(ValueChangeEvent<String> event) {
				Library.getStkService().selectProduct(txtProCode.getText(),
						proCallback);
			}
		});

		txtProCode.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					// curItem = findList(txtProCode.getText());
					if (invoice.items.size() < ITEM_LIMIT
							&& invoice.contCode.equals("999999")
							|| !invoice.contCode.equals("999999")) {
						curItem = null;
						if (curItem == null) {
							Library.getStkService().selectProduct(
									txtProCode.getText(), proCallback);
						} else {
							curItem.qty++;
							refreshItem();
							refreshInvoice();
						}
					} else {
						Window.alert("บิลเงินสดอย่างย่อ เพิ่มได้ไม่เกิน "
								+ ITEM_LIMIT + " รายการ");
					}
				} else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
					curItem = null;
					refreshItem();
				} else if (event.isControlKeyDown()
						&& event.getNativeKeyCode() == ' ') {
					btnProduct.click();
				}
			}
		});
		Label lblNewLabel_2 = new Label("รหัสสินค้า");
		editPanel.add(lblNewLabel_2, 8, 9);

		editPanel.add(txtProName, 330, 4);
		txtProName.setSize("337px", "18px");

		Label lblNewLabel_3 = new Label("ชื่อสินค้า");
		editPanel.add(lblNewLabel_3, 260, 10);

		Label lblNewLabel_4 = new Label("จำนวน");
		editPanel.add(lblNewLabel_4, 8, 42);

		editPanel.add(boxQty, 70, 39);
		boxQty.setSize("50px", "18px");
		boxQty.addValueChangeHandler(new ValueChangeHandler<Double>() {
			@Override
			public void onValueChange(ValueChangeEvent<Double> event) {
				curItem.qty = event.getValue();
				refreshItem();
				refreshInvoice();
			}
		});
		boxQty.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					txtProCode.setFocus(true);
					txtProCode.selectAll();
					// boxPrice.setFocus(true);
					// boxPrice.selectAll();
				}
			}
		});

		Label label = new Label("ราคา");
		editPanel.add(label, 130, 42);

		editPanel.add(boxPrice, 163, 39);
		boxPrice.setSize("80px", "18px");
		boxPrice.addValueChangeHandler(new ValueChangeHandler<Double>() {
			@Override
			public void onValueChange(ValueChangeEvent<Double> event) {
				curItem.unitPrice = event.getValue();
				refreshItem();
				refreshInvoice();

			}
		});
		boxPrice.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					boxDiscount.setFocus(true);
					boxDiscount.selectAll();
				}
			}
		});
		boxPrice.addFocusHandler(new FocusHandler() {
			public void onFocus(FocusEvent event) {
				boxPrice.selectAll();
			}
		});

		Label label1 = new Label("สวนลด(%)");
		editPanel.add(label1, 257, 42);
		boxDiscount.setAlignment(TextAlignment.RIGHT);

		editPanel.add(boxDiscount, 330, 39);
		boxDiscount.setSize("48px", "18px");
		boxDiscount.addValueChangeHandler(new ValueChangeHandler<Double>() {
			@Override
			public void onValueChange(ValueChangeEvent<Double> event) {
				// OverwriteLevel.show(FormInv.this);
				FormInv.this.veryfyDiscount();
				if (event.getValue() > curMaxDiscount) {
					refreshItem();
					Window.alert("Discount Over : " + curMaxDiscount + "%");
				} else {
					curItem.discount = event.getValue();
					refreshItem();
					refreshInvoice();
				}

			}
		});
		boxDiscount.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					// btnStock.setFocus(true);
					stkCombo.setFocus(true);
				}
				if (event.getNativeKeyCode() == KeyCodes.KEY_PAGEUP) {
					OverwriteLevel.show(FormInv.this, "022saleinvoice");
				}
			}
		});
		boxDiscount.addFocusHandler(new FocusHandler() {
			public void onFocus(FocusEvent event) {
				boxDiscount.selectAll();
			}
		});

		// Button btnDiscount = new Button("ลด");
		// btnDiscount.addClickHandler(new ClickHandler() {
		// public void onClick(ClickEvent event) {
		// OverwriteLevel.show(FormInv.this);
		// }
		// });
		// editPanel.add(btnDiscount, 375, 36);
		// btnDiscount.setSize("40px", "30px");

		// Label label_1 = new Label("คลัง");
		// editPanel.add(label_1, 520, 39);
		// label_1.setSize("36px", "18px");

		// editPanel.add(txtStkLoc, 517, 36);
		// txtStkLoc.setSize("50px", "18px");
		//
		// editPanel.add(txtStkCode, 617, 36);
		// txtStkCode.setSize("50px", "18px");
		// txtStkCode.setVisible(false);

		// editPanel.add(btnStock, 550, 36);
		// btnStock.setSize("100px", "30px");
		// btnStock.addClickHandler(new ClickHandler() {
		// public void onClick(ClickEvent event) {
		// StockPopup.popup.open(curItem);
		// }
		// });
		// StockPopup.popup.setTable(itemTable);
		stkCombo.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				curItem.stkCode = stkCombo.getValue(stkCombo.getSelectedIndex());
				itemTable.redraw();
			}
		});
		stkCombo.addKeyDownHandler(new KeyDownHandler() {

			@Override
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					txtProCode.setFocus(true);
					txtProCode.selectAll();
				}
			}
		});
		editPanel.add(stkCombo, 545, 38);
		stkCombo.setSize("132px", "22px");

		btnDelItem.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (mode == Library.FormMode.Insert
						|| mode == Library.FormMode.Edit) {
					invoice.items.remove(curItem);
					curItem = null;
					refreshItem();
					refreshInvoice();
				}
			}
		});
		btnDelItem.setTabIndex(-1);
		editPanel.add(btnDelItem, 750, 5);
		btnDelItem.setSize("100px", "30px");

		Label label_1 = new Label("คลัง");
		editPanel.add(label_1, 506, 40);

		editPanel.add(lbOrder, 750, 42);
		lbOrder.setSize("100px", "28px");
		return vPanel;
	}

	protected int findOrder(InvItem selected) {
		int x = 0;
		for (int i = 0; i < invoice.items.size() && x == 0; i++) {
			InvItem item = invoice.items.get(i);
			if (item.hashCode() == selected.hashCode()) {
				x = i + 1;
			}
		}
		return x;
	}

	protected InvItem findList(String proCode) {
		InvItem invitem = null;
		if (invoice.items.size() > 0) {
			int i = invoice.items.size() - 1;
			// for (int i = itemList.size() - 1; i >= 0 && invitem == null; i--)
			if (invoice.items.get(i).proCode.equals(proCode))
				invitem = invoice.items.get(i);
		}
		if (invitem != null)
			itemSelection.setSelected(invitem, true);
		return invitem;
	}

	@Override
	public void execute(int execode) {
		if (execode != -1) {
			userLevel = execode;
			btnManager.setVisible(userLevel == 5 || userLevel == 8
					|| userLevel == 9);
			btnRePrint.setVisible(userLevel == 4 || userLevel == 6
					|| userLevel == 7 || userLevel == 9);
		} else {
			Window.alert("Verify Fail!");
		}
		Window.alert("user level = " + userLevel);
	}

	protected void calcItem() {
		int i = 0;
		invoice.totalVat = 0.0;
		invoice.totalAmt = 0.0;
		invoice.totalItem = 0.0;

		double price;
		double totalItem = 0;
		for (InvItem item : invoice.items) {
			// if (item.dcLevel > 0)
			// item.discount = Library.discountSeries(item.product,
			// item.dcLevel);
			// item.item = ++i;
			totalItem = item.qty * item.unitPrice;
			price = totalItem * (100 - item.discount);
			if (item.product.minPrice > 0
					&& item.unitPrice < item.product.minPrice)
				item.unitPrice = item.product.minPrice;
			item.total = Math.round(price) / 100.0;
			item.vatAmt = item.total * item.vat;
			invoice.totalVat += item.vatAmt;
			invoice.totalItem += item.total;
			invoice.totalAmt += item.total + item.vatAmt;
		}

		invoice.totalVat = Math.round(invoice.totalVat * 100) / 100.0;
		// invoice.totalItem = invoice.totalAmt - invoice.totalVat;
		invoice.totalAmt = Math.round(invoice.totalAmt * 100) / 100.0;
		invoice.totalAmt -= invoice.spcDeduct;
		invoice.totalAmtText = Library.moneyText(invoice.totalAmt);

		// InvItem item = itemSelection.getSelectedObject();
		// if (item == null && itemList.size() > 0)
		// itemSelection.setSelected(itemList.get(0), true);
		// item = itemSelection.getSelectedObject();
	}

	AsyncCallback<List<Double>> vatCallback = new AsyncCallback<List<Double>>() {

		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(List<Double> result) {
			if (result != null) {
				vat = result;
			}

		}
	};

	protected void insertPayment() {
		if ((mode == Library.FormMode.Insert || mode == Library.FormMode.Edit)
				&& boxPayAmt.getValue() > 0) {
			if ((txtCheck.getText() != null || !txtCheck.isVisible())
					&& (boxCheckDate.getValue() != null || !boxCheckDate
							.isVisible())) {
				curPay.amt = boxPayAmt.getValue();
				if (curPay == null && curPay.amt == null)
					curPay.amt = 0.0;
				// curPay.payDate = boxCheckDate.getValue();
				curPay.checkDate = boxCheckDate.getValue();
				curPay.payMethod = Integer.parseInt(txtPayMeth.getText());
				curPay.payMethodName = txtPayMethod.getText();
				curPay.chkCardNo = txtCheck.getText();
				curPay.systemKind = invoice.systemKind;

				Double balance = customer.custLimit - customer.custBalance;
				if (curPay.payMethod == 0 && curPay.amt.compareTo(balance) > 0) {
					Window.alert("เกินวงเงินค้างชำระ "
							+ Library.moneyFormat(curPay.amt));
				} else {
					double paid = 0;
					for (Payment p : invoice.payments)
						paid += p.amt;
					double x = invoice.totalAmt - paid;
					if (Library.compare(curPay.amt, x) <= 0) {
						if (curPay.payMethod != 0)
							invoice.totalPaid += curPay.amt;
						invoice.payments.add(curPay);
						curPay = null;
						refreshPayments();
						refreshInvoice();
					} else {
						Window.alert("ชำระเกินยอดบิล " + Library.moneyFormat(x));
					}
				}
			} else {
				Window.alert("ข้อมูลการชำระไม่ครบ");
			}
		}
	}

	protected void deletePayment() {
		if (mode == Library.FormMode.Insert || mode == Library.FormMode.Edit) {
			invoice.payments.remove(curPay);
			if (curPay.payMethod != null && curPay.payMethod != 0) {
				invoice.totalPaid -= curPay.amt;
			}
			refreshPayments();
			refreshInvoice();
		}
	}

	private AsyncCallback<String> reportCallback = new AsyncCallback<String>() {
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(String result) {
			// Window.open(Window.Location.getPath()
			// + "applet/report.jsp?sessionReport=" + result, "APPLET",
			// "features");

			Window.open(
					Window.Location.getPath() + "output/" + result + ".pdf",
					"PDF", "features");

		}
	};

	private AsyncCallback<Integer> levelCallback = new AsyncCallback<Integer>() {
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(Integer result) {
			userLevel = result;
		}
	};

	protected double curMaxDiscount = 0;

	protected void veryfyDiscount() {
		if (curItem != null) {
			curMaxDiscount = curItem.product.discount;

			if (userLevel == 2 || userLevel == 3 || userLevel >= 7) {
				curMaxDiscount += (100 - curMaxDiscount) * curItem.product.dc1
						/ 100.0;
			}
			if (userLevel == 3 || userLevel >= 7) {
				curMaxDiscount += (100 - curMaxDiscount) * curItem.product.dc2
						/ 100.0;
			}
			if (userLevel == 3 || userLevel >= 7) {
				curMaxDiscount += (100 - curMaxDiscount) * curItem.product.dc3
						/ 100.0;
			}
			if (userLevel == 3 || userLevel >= 7) {
				curMaxDiscount += (100 - curMaxDiscount) * curItem.product.dc4
						/ 100.0;
			}
			if (userLevel >= 7) {
				curMaxDiscount += (100 - curMaxDiscount) * curItem.product.dc5
						/ 100.0;
			}
		}
	}

	public void printReport(final Map<String, Object> params) {
		String reportFile = "report004.jasper";
		if (invoice.contCode.equals("999999"))
			reportFile = "report004.jasper";
		else if (invoice.docuKind.equals("I"))
			reportFile = "report005.jasper";
		else if (invoice.docuKind.equals("C")) {
			reportFile = "report006.jasper";
		} else if (invoice.docuKind.equals("S"))
			reportFile = "report007.jasper";
		else if (invoice.docuKind.equals("R"))
			reportFile = "report008.jasper";
		else if (invoice.docuKind.equals("Q"))
			reportFile = "report009.jasper";
		else if (invoice.docuKind.equals("T"))
			reportFile = "report010.jasper";
		Library.getService().fillReport(reportFile, params, reportCallback);
	}

	public void setFields() {
		invoice.invDate = txtSaleDate.getValue();
		invoice.shipDate = txtShipDate.getValue();
		invoice.dueDate = txtDueDate.getValue();
		invoice.poNr = txtPoNr.getText();
		invoice.projCode = txtProCode.getText();
		invoice.contactAddr = txtAddr.getText();
		invoice.note = txtComment.getText();
		invoice.shipTo = txtShipTo.getText();
	}

	KeyPressHandler keyHandler = new KeyPressHandler() {

		@Override
		public void onKeyPress(KeyPressEvent event) {
			if (event.getCharCode() == KeyCodes.KEY_ESCAPE)
				clearScreen();
		}
	};

	public void addShortCut() {
		for (Widget obj : this.getChildren()) {
			if (obj instanceof Button || obj instanceof TextBox) {
				((Button) obj).addKeyPressHandler(keyHandler);
			}
		}
	}
}
